/**
 * 用户批量删除接口测试用例
 *
 * Created by snowingsea on 2020/02/01.
 */
const chai = require('chai');
const should = chai.should(); // eslint-disable-line no-unused-vars
chai.use(require('chai-http'));

const common = require('./../../common');
const Administrator = require('./../../../models/administrator');
const uri = require('./../uri');
const { roleKind, statusKind } = require('./../../../../phoenix/models/users');

module.exports = describe('/DELETE users.json', function () {
  const url = '/users.json';
  const administrator = new Administrator();
  const newUserIds = [];
  after(function (done) {
    administrator.removeUsers(newUserIds)
      .then(() => {
        done();
      })
      .catch(done);
  });

  common.should.be.user(uri, url, 'delete');
  common.should.be.administrator(uri, url, 'delete');

  // 正常删除
  it('it should DELETE users', function (done) {
    let newUsers;
    let userTotalNumber;
    let newUserTotalNumber;
    const newUserCount = 10;
    administrator.getUserTotalNumber()
      .then((totalNumber) => {
        userTotalNumber = totalNumber;
        // 随机添加用户
        return administrator.createRandomUsers(newUserCount);
      })
      .then((users) => {
        newUsers = users;
        return administrator.getUserTotalNumber();
      })
      .then((totalNumber) => {
        newUserTotalNumber = totalNumber;
        return administrator.login();
      })
      .then(() => {
        chai.request(uri)
          .delete(url)
          .set('Authorization', `Bearer ${administrator.token.accessToken}`)
          .query({ userIds: newUsers.map(({ userId }) => userId) })
          .end((err, res) => {
            administrator.getUserTotalNumber()
              .then((totalNumber) => {
                res.should.have.status(204);
                newUserTotalNumber.should.be.eql(userTotalNumber + newUserCount);
                totalNumber.should.be.eql(userTotalNumber);
                done();
              })
              .catch(done);
          });
      })
      .catch(done);
  });

  // 反选删除
  it('it should delete users except original users', function (done) {
    let exceptUsers;
    administrator.createRandomUser()
      .then(({ userId }) => {
        newUserIds.push(userId);
        return administrator.getAllUsers();
      })
      .then((users) => {
        exceptUsers = users;
        return administrator.createRandomUsers();
      })
      .then(() => administrator.login())
      .then(() => {
        chai.request(uri)
          .delete(url)
          .set('Authorization', `Bearer ${administrator.token.accessToken}`)
          .query({ exceptUserIds: exceptUsers.map(({ userId }) => userId) })
          .end((err, res) => {
            administrator.login()
              .then(() => administrator.getUserTotalNumber())
              .then((totalNumber) => {
                res.should.have.status(204);
                totalNumber.should.be.eql(exceptUsers.length);
                done();
              })
              .catch(done);
          });
      })
      .catch(done);
  });

  // 删除测试人员
  it('it should delete tester except one', function (done) {
    const exceptUserIds = new Set();
    let remainCount = 0;
    administrator.getAllUsers()
      .then((users) => {
        users.forEach(({ userId }) => {
          exceptUserIds.add(userId);
        });
        return administrator.createRandomTester();
      })
      .then(({ userId }) => {
        exceptUserIds.add(userId);
        newUserIds.push(userId);
        return administrator.createRandomUsers();
      })
      .then((users) => {
        users.forEach(({ userId }) => {
          newUserIds.push(userId);
        });
        return administrator.getAllUsers();
      })
      .then((users) => {
        const testers = users.filter((user) => {
          const { role } = user;
          return (role & roleKind.tester) > 0; // eslint-disable-line no-bitwise
        });
        let deleteCount = 0;
        testers.forEach(({ userId }) => {
          if (!exceptUserIds.has(userId)) {
            deleteCount += 1;
          }
        });
        remainCount = users.length - deleteCount;

        chai.request(uri)
          .delete(url)
          .set('Authorization', `Bearer ${administrator.token.accessToken}`)
          .query({ exceptUserIds: [...exceptUserIds], roles: [roleKind.tester] })
          .end((err, res) => {
            administrator.login()
              .then(() => administrator.getUserTotalNumber())
              .then((totalNumber) => {
                res.should.have.status(204);
                totalNumber.should.be.eql(remainCount);
                done();
              })
              .catch(done);
          });
      })
      .catch(done);
  });

  // 删除未激活用户
  it('it should delete unactivated users except one', function (done) {
    const exceptUserIds = new Set();
    let remainCount = 0;
    administrator.getAllUsers()
      .then((users) => {
        users.forEach(({ userId }) => {
          exceptUserIds.add(userId);
        });
        return administrator.createRandomUser();
      })
      .then(({ userId }) => {
        exceptUserIds.add(userId);
        newUserIds.push(userId);
        return administrator.createRandomUsers();
      })
      .then((users) => {
        users.forEach(({ userId }) => {
          newUserIds.push(userId);
        });
        return administrator.getAllUsers();
      })
      .then((users) => {
        const unactivatedUsers = users.filter(({ status }) => status === statusKind.unactivated);
        let deleteCount = 0;
        unactivatedUsers.forEach(({ userId }) => {
          if (!exceptUserIds.has(userId)) {
            deleteCount += 1;
          }
        });
        remainCount = users.length - deleteCount;

        chai.request(uri)
          .delete(url)
          .set('Authorization', `Bearer ${administrator.token.accessToken}`)
          .query({ exceptUserIds: [...exceptUserIds], status: [statusKind.unactivated] })
          .end((err, res) => {
            administrator.login()
              .then(() => administrator.getUserTotalNumber())
              .then((totalNumber) => {
                res.should.have.status(204);
                totalNumber.should.be.eql(remainCount);
                done();
              })
              .catch(done);
          });
      })
      .catch(done);
  });
});
